1 /* 2 * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt; 27 28 /** 29 * A set of attributes which control a print job. 30 * <p> 31 * Instances of this class control the number of copies, default selection, 32 * destination, print dialog, file and printer names, page ranges, multiple 33 * document handling (including collation), and multi-page imposition (such 34 * as duplex) of every print job which uses the instance. Attribute names are 35 * compliant with the Internet Printing Protocol (IPP) 1.1 where possible. 36 * Attribute values are partially compliant where possible. 37 * <p> 38 * To use a method which takes an inner class type, pass a reference to 39 * one of the constant fields of the inner class. Client code cannot create 40 * new instances of the inner class types because none of those classes 41 * has a public constructor. For example, to set the print dialog type to 42 * the cross-platform, pure Java print dialog, use the following code: 43 * <pre> 44 * import java.awt.JobAttributes; 45 * 46 * public class PureJavaPrintDialogExample { 47 * public void setPureJavaPrintDialog(JobAttributes jobAttributes) { 48 * jobAttributes.setDialog(JobAttributes.DialogType.COMMON); 49 * } 50 * } 51 * </pre> 52 * <p> 53 * Every IPP attribute which supports an <i>attributeName</i>-default value 54 * has a corresponding <code>set<i>attributeName</i>ToDefault</code> method. 55 * Default value fields are not provided. 56 * 57 * @author David Mendenhall 58 * @since 1.3 59 */ 60 public final class JobAttributes implements Cloneable { 61 /** 62 * A type-safe enumeration of possible default selection states. 63 * @since 1.3 64 */ 65 public static final class DefaultSelectionType extends AttributeValue { 66 private static final int I_ALL = 0; 67 private static final int I_RANGE = 1; 68 private static final int I_SELECTION = 2; 69 70 private static final String NAMES[] = { 71 "all", "range", "selection" 72 }; 73 74 /** 75 * The <code>DefaultSelectionType</code> instance to use for 76 * specifying that all pages of the job should be printed. 77 */ 78 public static final DefaultSelectionType ALL = 79 new DefaultSelectionType(I_ALL); 80 /** 81 * The <code>DefaultSelectionType</code> instance to use for 82 * specifying that a range of pages of the job should be printed. 83 */ 84 public static final DefaultSelectionType RANGE = 85 new DefaultSelectionType(I_RANGE); 86 /** 87 * The <code>DefaultSelectionType</code> instance to use for 88 * specifying that the current selection should be printed. 89 */ 90 public static final DefaultSelectionType SELECTION = 91 new DefaultSelectionType(I_SELECTION); 92 93 private DefaultSelectionType(int type) { 94 super(type, NAMES); 95 } 96 } 97 98 /** 99 * A type-safe enumeration of possible job destinations. 100 * @since 1.3 101 */ 102 public static final class DestinationType extends AttributeValue { 103 private static final int I_FILE = 0; 104 private static final int I_PRINTER = 1; 105 106 private static final String NAMES[] = { 107 "file", "printer" 108 }; 109 110 /** 111 * The <code>DestinationType</code> instance to use for 112 * specifying print to file. 113 */ 114 public static final DestinationType FILE = 115 new DestinationType(I_FILE); 116 /** 117 * The <code>DestinationType</code> instance to use for 118 * specifying print to printer. 119 */ 120 public static final DestinationType PRINTER = 121 new DestinationType(I_PRINTER); 122 123 private DestinationType(int type) { 124 super(type, NAMES); 125 } 126 } 127 128 /** 129 * A type-safe enumeration of possible dialogs to display to the user. 130 * @since 1.3 131 */ 132 public static final class DialogType extends AttributeValue { 133 private static final int I_COMMON = 0; 134 private static final int I_NATIVE = 1; 135 private static final int I_NONE = 2; 136 137 private static final String NAMES[] = { 138 "common", "native", "none" 139 }; 140 141 /** 142 * The <code>DialogType</code> instance to use for 143 * specifying the cross-platform, pure Java print dialog. 144 */ 145 public static final DialogType COMMON = new DialogType(I_COMMON); 146 /** 147 * The <code>DialogType</code> instance to use for 148 * specifying the platform's native print dialog. 149 */ 150 public static final DialogType NATIVE = new DialogType(I_NATIVE); 151 /** 152 * The <code>DialogType</code> instance to use for 153 * specifying no print dialog. 154 */ 155 public static final DialogType NONE = new DialogType(I_NONE); 156 157 private DialogType(int type) { 158 super(type, NAMES); 159 } 160 } 161 162 /** 163 * A type-safe enumeration of possible multiple copy handling states. 164 * It is used to control how the sheets of multiple copies of a single 165 * document are collated. 166 * @since 1.3 167 */ 168 public static final class MultipleDocumentHandlingType extends 169 AttributeValue { 170 private static final int I_SEPARATE_DOCUMENTS_COLLATED_COPIES = 0; 171 private static final int I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = 1; 172 173 private static final String NAMES[] = { 174 "separate-documents-collated-copies", 175 "separate-documents-uncollated-copies" 176 }; 177 178 /** 179 * The <code>MultipleDocumentHandlingType</code> instance to use for specifying 180 * that the job should be divided into separate, collated copies. 181 */ 182 public static final MultipleDocumentHandlingType 183 SEPARATE_DOCUMENTS_COLLATED_COPIES = 184 new MultipleDocumentHandlingType( 185 I_SEPARATE_DOCUMENTS_COLLATED_COPIES); 186 /** 187 * The <code>MultipleDocumentHandlingType</code> instance to use for specifying 188 * that the job should be divided into separate, uncollated copies. 189 */ 190 public static final MultipleDocumentHandlingType 191 SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = 192 new MultipleDocumentHandlingType( 193 I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES); 194 195 private MultipleDocumentHandlingType(int type) { 196 super(type, NAMES); 197 } 198 } 199 200 /** 201 * A type-safe enumeration of possible multi-page impositions. These 202 * impositions are in compliance with IPP 1.1. 203 * @since 1.3 204 */ 205 public static final class SidesType extends AttributeValue { 206 private static final int I_ONE_SIDED = 0; 207 private static final int I_TWO_SIDED_LONG_EDGE = 1; 208 private static final int I_TWO_SIDED_SHORT_EDGE = 2; 209 210 private static final String NAMES[] = { 211 "one-sided", "two-sided-long-edge", "two-sided-short-edge" 212 }; 213 214 /** 215 * The <code>SidesType</code> instance to use for specifying that 216 * consecutive job pages should be printed upon the same side of 217 * consecutive media sheets. 218 */ 219 public static final SidesType ONE_SIDED = new SidesType(I_ONE_SIDED); 220 /** 221 * The <code>SidesType</code> instance to use for specifying that 222 * consecutive job pages should be printed upon front and back sides 223 * of consecutive media sheets, such that the orientation of each pair 224 * of pages on the medium would be correct for the reader as if for 225 * binding on the long edge. 226 */ 227 public static final SidesType TWO_SIDED_LONG_EDGE = 228 new SidesType(I_TWO_SIDED_LONG_EDGE); 229 /** 230 * The <code>SidesType</code> instance to use for specifying that 231 * consecutive job pages should be printed upon front and back sides 232 * of consecutive media sheets, such that the orientation of each pair 233 * of pages on the medium would be correct for the reader as if for 234 * binding on the short edge. 235 */ 236 public static final SidesType TWO_SIDED_SHORT_EDGE = 237 new SidesType(I_TWO_SIDED_SHORT_EDGE); 238 239 private SidesType(int type) { 240 super(type, NAMES); 241 } 242 } 243 244 private int copies; 245 private DefaultSelectionType defaultSelection; 246 private DestinationType destination; 247 private DialogType dialog; 248 private String fileName; 249 private int fromPage; 250 private int maxPage; 251 private int minPage; 252 private MultipleDocumentHandlingType multipleDocumentHandling; 253 private int[][] pageRanges; 254 private int prFirst; 255 private int prLast; 256 private String printer; 257 private SidesType sides; 258 private int toPage; 259 260 /** 261 * Constructs a <code>JobAttributes</code> instance with default 262 * values for every attribute. The dialog defaults to 263 * <code>DialogType.NATIVE</code>. Min page defaults to 264 * <code>1</code>. Max page defaults to <code>Integer.MAX_VALUE</code>. 265 * Destination defaults to <code>DestinationType.PRINTER</code>. 266 * Selection defaults to <code>DefaultSelectionType.ALL</code>. 267 * Number of copies defaults to <code>1</code>. Multiple document handling defaults 268 * to <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>. 269 * Sides defaults to <code>SidesType.ONE_SIDED</code>. File name defaults 270 * to <code>null</code>. 271 */ 272 public JobAttributes() { 273 setCopiesToDefault(); 274 setDefaultSelection(DefaultSelectionType.ALL); 275 setDestination(DestinationType.PRINTER); 276 setDialog(DialogType.NATIVE); 277 setMaxPage(Integer.MAX_VALUE); 278 setMinPage(1); 279 setMultipleDocumentHandlingToDefault(); 280 setSidesToDefault(); 281 } 282 283 /** 284 * Constructs a <code>JobAttributes</code> instance which is a copy 285 * of the supplied <code>JobAttributes</code>. 286 * 287 * @param obj the <code>JobAttributes</code> to copy 288 */ 289 public JobAttributes(JobAttributes obj) { 290 set(obj); 291 } 292 293 /** 294 * Constructs a <code>JobAttributes</code> instance with the 295 * specified values for every attribute. 296 * 297 * @param copies an integer greater than 0 298 * @param defaultSelection <code>DefaultSelectionType.ALL</code>, 299 * <code>DefaultSelectionType.RANGE</code>, or 300 * <code>DefaultSelectionType.SELECTION</code> 301 * @param destination <code>DesintationType.FILE</code> or 302 * <code>DesintationType.PRINTER</code> 303 * @param dialog <code>DialogType.COMMON</code>, 304 * <code>DialogType.NATIVE</code>, or 305 * <code>DialogType.NONE</code> 306 * @param fileName the possibly <code>null</code> file name 307 * @param maxPage an integer greater than zero and greater than or equal 308 * to <i>minPage</i> 309 * @param minPage an integer greater than zero and less than or equal 310 * to <i>maxPage</i> 311 * @param multipleDocumentHandling 312 * <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES</code> or 313 * <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code> 314 * @param pageRanges an array of integer arrays of two elements; an array 315 * is interpreted as a range spanning all pages including and 316 * between the specified pages; ranges must be in ascending 317 * order and must not overlap; specified page numbers cannot be 318 * less than <i>minPage</i> nor greater than <i>maxPage</i>; 319 * for example: 320 * <pre> 321 * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 }, 322 * new int[] { 15, 19 } }), 323 * </pre> 324 * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that 325 * (<code>new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }</code>), 326 * is an invalid set of page ranges because the two ranges 327 * overlap 328 * @param printer the possibly <code>null</code> printer name 329 * @param sides <code>SidesType.ONE_SIDED</code>, 330 * <code>SidesType.TWO_SIDED_LONG_EDGE</code>, or 331 * <code>SidesType.TWO_SIDED_SHORT_EDGE</code> 332 * @throws IllegalArgumentException if one or more of the above 333 * conditions is violated 334 */ 335 public JobAttributes(int copies, DefaultSelectionType defaultSelection, 336 DestinationType destination, DialogType dialog, 337 String fileName, int maxPage, int minPage, 338 MultipleDocumentHandlingType multipleDocumentHandling, 339 int[][] pageRanges, String printer, SidesType sides) { 340 setCopies(copies); 341 setDefaultSelection(defaultSelection); 342 setDestination(destination); 343 setDialog(dialog); 344 setFileName(fileName); 345 setMaxPage(maxPage); 346 setMinPage(minPage); 347 setMultipleDocumentHandling(multipleDocumentHandling); 348 setPageRanges(pageRanges); 349 setPrinter(printer); 350 setSides(sides); 351 } 352 353 /** 354 * Creates and returns a copy of this <code>JobAttributes</code>. 355 * 356 * @return the newly created copy; it is safe to cast this Object into 357 * a <code>JobAttributes</code> 358 */ 359 public Object clone() { 360 try { 361 return super.clone(); 362 } catch (CloneNotSupportedException e) { 363 // Since we implement Cloneable, this should never happen 364 throw new InternalError(); 365 } 366 } 367 368 /** 369 * Sets all of the attributes of this <code>JobAttributes</code> to 370 * the same values as the attributes of obj. 371 * 372 * @param obj the <code>JobAttributes</code> to copy 373 */ 374 public void set(JobAttributes obj) { 375 copies = obj.copies; 376 defaultSelection = obj.defaultSelection; 377 destination = obj.destination; 378 dialog = obj.dialog; 379 fileName = obj.fileName; 380 fromPage = obj.fromPage; 381 maxPage = obj.maxPage; 382 minPage = obj.minPage; 383 multipleDocumentHandling = obj.multipleDocumentHandling; 384 // okay because we never modify the contents of pageRanges 385 pageRanges = obj.pageRanges; 386 prFirst = obj.prFirst; 387 prLast = obj.prLast; 388 printer = obj.printer; 389 sides = obj.sides; 390 toPage = obj.toPage; 391 } 392 393 /** 394 * Returns the number of copies the application should render for jobs 395 * using these attributes. This attribute is updated to the value chosen 396 * by the user. 397 * 398 * @return an integer greater than 0. 399 */ 400 public int getCopies() { 401 return copies; 402 } 403 404 /** 405 * Specifies the number of copies the application should render for jobs 406 * using these attributes. Not specifying this attribute is equivalent to 407 * specifying <code>1</code>. 408 * 409 * @param copies an integer greater than 0 410 * @throws IllegalArgumentException if <code>copies</code> is less than 411 * or equal to 0 412 */ 413 public void setCopies(int copies) { 414 if (copies <= 0) { 415 throw new IllegalArgumentException("Invalid value for attribute "+ 416 "copies"); 417 } 418 this.copies = copies; 419 } 420 421 /** 422 * Sets the number of copies the application should render for jobs using 423 * these attributes to the default. The default number of copies is 1. 424 */ 425 public void setCopiesToDefault() { 426 setCopies(1); 427 } 428 429 /** 430 * Specifies whether, for jobs using these attributes, the application 431 * should print all pages, the range specified by the return value of 432 * <code>getPageRanges</code>, or the current selection. This attribute 433 * is updated to the value chosen by the user. 434 * 435 * @return DefaultSelectionType.ALL, DefaultSelectionType.RANGE, or 436 * DefaultSelectionType.SELECTION 437 */ 438 public DefaultSelectionType getDefaultSelection() { 439 return defaultSelection; 440 } 441 442 /** 443 * Specifies whether, for jobs using these attributes, the application 444 * should print all pages, the range specified by the return value of 445 * <code>getPageRanges</code>, or the current selection. Not specifying 446 * this attribute is equivalent to specifying DefaultSelectionType.ALL. 447 * 448 * @param defaultSelection DefaultSelectionType.ALL, 449 * DefaultSelectionType.RANGE, or DefaultSelectionType.SELECTION. 450 * @throws IllegalArgumentException if defaultSelection is <code>null</code> 451 */ 452 public void setDefaultSelection(DefaultSelectionType defaultSelection) { 453 if (defaultSelection == null) { 454 throw new IllegalArgumentException("Invalid value for attribute "+ 455 "defaultSelection"); 456 } 457 this.defaultSelection = defaultSelection; 458 } 459 460 /** 461 * Specifies whether output will be to a printer or a file for jobs using 462 * these attributes. This attribute is updated to the value chosen by the 463 * user. 464 * 465 * @return DesintationType.FILE or DesintationType.PRINTER 466 */ 467 public DestinationType getDestination() { 468 return destination; 469 } 470 471 /** 472 * Specifies whether output will be to a printer or a file for jobs using 473 * these attributes. Not specifying this attribute is equivalent to 474 * specifying DesintationType.PRINTER. 475 * 476 * @param destination DesintationType.FILE or DesintationType.PRINTER. 477 * @throws IllegalArgumentException if destination is null. 478 */ 479 public void setDestination(DestinationType destination) { 480 if (destination == null) { 481 throw new IllegalArgumentException("Invalid value for attribute "+ 482 "destination"); 483 } 484 this.destination = destination; 485 } 486 487 /** 488 * Returns whether, for jobs using these attributes, the user should see 489 * a print dialog in which to modify the print settings, and which type of 490 * print dialog should be displayed. DialogType.COMMON denotes a cross- 491 * platform, pure Java print dialog. DialogType.NATIVE denotes the 492 * platform's native print dialog. If a platform does not support a native 493 * print dialog, the pure Java print dialog is displayed instead. 494 * DialogType.NONE specifies no print dialog (i.e., background printing). 495 * This attribute cannot be modified by, and is not subject to any 496 * limitations of, the implementation or the target printer. 497 * 498 * @return <code>DialogType.COMMON</code>, <code>DialogType.NATIVE</code>, or 499 * <code>DialogType.NONE</code> 500 */ 501 public DialogType getDialog() { 502 return dialog; 503 } 504 505 /** 506 * Specifies whether, for jobs using these attributes, the user should see 507 * a print dialog in which to modify the print settings, and which type of 508 * print dialog should be displayed. DialogType.COMMON denotes a cross- 509 * platform, pure Java print dialog. DialogType.NATIVE denotes the 510 * platform's native print dialog. If a platform does not support a native 511 * print dialog, the pure Java print dialog is displayed instead. 512 * DialogType.NONE specifies no print dialog (i.e., background printing). 513 * Not specifying this attribute is equivalent to specifying 514 * DialogType.NATIVE. 515 * 516 * @param dialog DialogType.COMMON, DialogType.NATIVE, or 517 * DialogType.NONE. 518 * @throws IllegalArgumentException if dialog is null. 519 */ 520 public void setDialog(DialogType dialog) { 521 if (dialog == null) { 522 throw new IllegalArgumentException("Invalid value for attribute "+ 523 "dialog"); 524 } 525 this.dialog = dialog; 526 } 527 528 /** 529 * Specifies the file name for the output file for jobs using these 530 * attributes. This attribute is updated to the value chosen by the user. 531 * 532 * @return the possibly <code>null</code> file name 533 */ 534 public String getFileName() { 535 return fileName; 536 } 537 538 /** 539 * Specifies the file name for the output file for jobs using these 540 * attributes. Default is platform-dependent and implementation-defined. 541 * 542 * @param fileName the possibly null file name. 543 */ 544 public void setFileName(String fileName) { 545 this.fileName = fileName; 546 } 547 548 /** 549 * Returns, for jobs using these attributes, the first page to be 550 * printed, if a range of pages is to be printed. This attribute is 551 * updated to the value chosen by the user. An application should ignore 552 * this attribute on output, unless the return value of the <code> 553 * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An 554 * application should honor the return value of <code>getPageRanges</code> 555 * over the return value of this method, if possible. 556 * 557 * @return an integer greater than zero and less than or equal to 558 * <i>toPage</i> and greater than or equal to <i>minPage</i> and 559 * less than or equal to <i>maxPage</i>. 560 */ 561 public int getFromPage() { 562 if (fromPage != 0) { 563 return fromPage; 564 } else if (toPage != 0) { 565 return getMinPage(); 566 } else if (pageRanges != null) { 567 return prFirst; 568 } else { 569 return getMinPage(); 570 } 571 } 572 573 /** 574 * Specifies, for jobs using these attributes, the first page to be 575 * printed, if a range of pages is to be printed. If this attribute is not 576 * specified, then the values from the pageRanges attribute are used. If 577 * pageRanges and either or both of fromPage and toPage are specified, 578 * pageRanges takes precedence. Specifying none of pageRanges, fromPage, 579 * or toPage is equivalent to calling 580 * setPageRanges(new int[][] { new int[] { <i>minPage</i> } }); 581 * 582 * @param fromPage an integer greater than zero and less than or equal to 583 * <i>toPage</i> and greater than or equal to <i>minPage</i> and 584 * less than or equal to <i>maxPage</i>. 585 * @throws IllegalArgumentException if one or more of the above 586 * conditions is violated. 587 */ 588 public void setFromPage(int fromPage) { 589 if (fromPage <= 0 || 590 (toPage != 0 && fromPage > toPage) || 591 fromPage < minPage || 592 fromPage > maxPage) { 593 throw new IllegalArgumentException("Invalid value for attribute "+ 594 "fromPage"); 595 } 596 this.fromPage = fromPage; 597 } 598 599 /** 600 * Specifies the maximum value the user can specify as the last page to 601 * be printed for jobs using these attributes. This attribute cannot be 602 * modified by, and is not subject to any limitations of, the 603 * implementation or the target printer. 604 * 605 * @return an integer greater than zero and greater than or equal 606 * to <i>minPage</i>. 607 */ 608 public int getMaxPage() { 609 return maxPage; 610 } 611 612 /** 613 * Specifies the maximum value the user can specify as the last page to 614 * be printed for jobs using these attributes. Not specifying this 615 * attribute is equivalent to specifying <code>Integer.MAX_VALUE</code>. 616 * 617 * @param maxPage an integer greater than zero and greater than or equal 618 * to <i>minPage</i> 619 * @throws IllegalArgumentException if one or more of the above 620 * conditions is violated 621 */ 622 public void setMaxPage(int maxPage) { 623 if (maxPage <= 0 || maxPage < minPage) { 624 throw new IllegalArgumentException("Invalid value for attribute "+ 625 "maxPage"); 626 } 627 this.maxPage = maxPage; 628 } 629 630 /** 631 * Specifies the minimum value the user can specify as the first page to 632 * be printed for jobs using these attributes. This attribute cannot be 633 * modified by, and is not subject to any limitations of, the 634 * implementation or the target printer. 635 * 636 * @return an integer greater than zero and less than or equal 637 * to <i>maxPage</i>. 638 */ 639 public int getMinPage() { 640 return minPage; 641 } 642 643 /** 644 * Specifies the minimum value the user can specify as the first page to 645 * be printed for jobs using these attributes. Not specifying this 646 * attribute is equivalent to specifying <code>1</code>. 647 * 648 * @param minPage an integer greater than zero and less than or equal 649 * to <i>maxPage</i>. 650 * @throws IllegalArgumentException if one or more of the above 651 * conditions is violated. 652 */ 653 public void setMinPage(int minPage) { 654 if (minPage <= 0 || minPage > maxPage) { 655 throw new IllegalArgumentException("Invalid value for attribute "+ 656 "minPage"); 657 } 658 this.minPage = minPage; 659 } 660 661 /** 662 * Specifies the handling of multiple copies, including collation, for 663 * jobs using these attributes. This attribute is updated to the value 664 * chosen by the user. 665 * 666 * @return 667 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or 668 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES. 669 */ 670 public MultipleDocumentHandlingType getMultipleDocumentHandling() { 671 return multipleDocumentHandling; 672 } 673 674 /** 675 * Specifies the handling of multiple copies, including collation, for 676 * jobs using these attributes. Not specifying this attribute is equivalent 677 * to specifying 678 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES. 679 * 680 * @param multipleDocumentHandling 681 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or 682 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES. 683 * @throws IllegalArgumentException if multipleDocumentHandling is null. 684 */ 685 public void setMultipleDocumentHandling(MultipleDocumentHandlingType 686 multipleDocumentHandling) { 687 if (multipleDocumentHandling == null) { 688 throw new IllegalArgumentException("Invalid value for attribute "+ 689 "multipleDocumentHandling"); 690 } 691 this.multipleDocumentHandling = multipleDocumentHandling; 692 } 693 694 /** 695 * Sets the handling of multiple copies, including collation, for jobs 696 * using these attributes to the default. The default handling is 697 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES. 698 */ 699 public void setMultipleDocumentHandlingToDefault() { 700 setMultipleDocumentHandling( 701 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES); 702 } 703 704 /** 705 * Specifies, for jobs using these attributes, the ranges of pages to be 706 * printed, if a range of pages is to be printed. All range numbers are 707 * inclusive. This attribute is updated to the value chosen by the user. 708 * An application should ignore this attribute on output, unless the 709 * return value of the <code>getDefaultSelection</code> method is 710 * DefaultSelectionType.RANGE. 711 * 712 * @return an array of integer arrays of 2 elements. An array 713 * is interpreted as a range spanning all pages including and 714 * between the specified pages. Ranges must be in ascending 715 * order and must not overlap. Specified page numbers cannot be 716 * less than <i>minPage</i> nor greater than <i>maxPage</i>. 717 * For example: 718 * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 }, 719 * new int[] { 15, 19 } }), 720 * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. 721 */ 722 public int[][] getPageRanges() { 723 if (pageRanges != null) { 724 // Return a copy because otherwise client code could circumvent the 725 // the checks made in setPageRanges by modifying the returned 726 // array. 727 int[][] copy = new int[pageRanges.length][2]; 728 for (int i = 0; i < pageRanges.length; i++) { 729 copy[i][0] = pageRanges[i][0]; 730 copy[i][1] = pageRanges[i][1]; 731 } 732 return copy; 733 } else if (fromPage != 0 || toPage != 0) { 734 int fromPage = getFromPage(); 735 int toPage = getToPage(); 736 return new int[][] { new int[] { fromPage, toPage } }; 737 } else { 738 int minPage = getMinPage(); 739 return new int[][] { new int[] { minPage, minPage } }; 740 } 741 } 742 743 /** 744 * Specifies, for jobs using these attributes, the ranges of pages to be 745 * printed, if a range of pages is to be printed. All range numbers are 746 * inclusive. If this attribute is not specified, then the values from the 747 * fromPage and toPages attributes are used. If pageRanges and either or 748 * both of fromPage and toPage are specified, pageRanges takes precedence. 749 * Specifying none of pageRanges, fromPage, or toPage is equivalent to 750 * calling setPageRanges(new int[][] { new int[] { <i>minPage</i>, 751 * <i>minPage</i> } }); 752 * 753 * @param pageRanges an array of integer arrays of 2 elements. An array 754 * is interpreted as a range spanning all pages including and 755 * between the specified pages. Ranges must be in ascending 756 * order and must not overlap. Specified page numbers cannot be 757 * less than <i>minPage</i> nor greater than <i>maxPage</i>. 758 * For example: 759 * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 }, 760 * new int[] { 15, 19 } }), 761 * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that 762 * (new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }), 763 * is an invalid set of page ranges because the two ranges 764 * overlap. 765 * @throws IllegalArgumentException if one or more of the above 766 * conditions is violated. 767 */ 768 public void setPageRanges(int[][] pageRanges) { 769 String xcp = "Invalid value for attribute pageRanges"; 770 int first = 0; 771 int last = 0; 772 773 if (pageRanges == null) { 774 throw new IllegalArgumentException(xcp); 775 } 776 777 for (int i = 0; i < pageRanges.length; i++) { 778 if (pageRanges[i] == null || 779 pageRanges[i].length != 2 || 780 pageRanges[i][0] <= last || 781 pageRanges[i][1] < pageRanges[i][0]) { 782 throw new IllegalArgumentException(xcp); 783 } 784 last = pageRanges[i][1]; 785 if (first == 0) { 786 first = pageRanges[i][0]; 787 } 788 } 789 790 if (first < minPage || last > maxPage) { 791 throw new IllegalArgumentException(xcp); 792 } 793 794 // Store a copy because otherwise client code could circumvent the 795 // the checks made above by holding a reference to the array and 796 // modifying it after calling setPageRanges. 797 int[][] copy = new int[pageRanges.length][2]; 798 for (int i = 0; i < pageRanges.length; i++) { 799 copy[i][0] = pageRanges[i][0]; 800 copy[i][1] = pageRanges[i][1]; 801 } 802 this.pageRanges = copy; 803 this.prFirst = first; 804 this.prLast = last; 805 } 806 807 /** 808 * Returns the destination printer for jobs using these attributes. This 809 * attribute is updated to the value chosen by the user. 810 * 811 * @return the possibly null printer name. 812 */ 813 public String getPrinter() { 814 return printer; 815 } 816 817 /** 818 * Specifies the destination printer for jobs using these attributes. 819 * Default is platform-dependent and implementation-defined. 820 * 821 * @param printer the possibly null printer name. 822 */ 823 public void setPrinter(String printer) { 824 this.printer = printer; 825 } 826 827 /** 828 * Returns how consecutive pages should be imposed upon the sides of the 829 * print medium for jobs using these attributes. SidesType.ONE_SIDED 830 * imposes each consecutive page upon the same side of consecutive media 831 * sheets. This imposition is sometimes called <i>simplex</i>. 832 * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages 833 * upon front and back sides of consecutive media sheets, such that the 834 * orientation of each pair of pages on the medium would be correct for 835 * the reader as if for binding on the long edge. This imposition is 836 * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes 837 * each consecutive pair of pages upon front and back sides of consecutive 838 * media sheets, such that the orientation of each pair of pages on the 839 * medium would be correct for the reader as if for binding on the short 840 * edge. This imposition is sometimes called <i>tumble</i>. This attribute 841 * is updated to the value chosen by the user. 842 * 843 * @return SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or 844 * SidesType.TWO_SIDED_SHORT_EDGE. 845 */ 846 public SidesType getSides() { 847 return sides; 848 } 849 850 /** 851 * Specifies how consecutive pages should be imposed upon the sides of the 852 * print medium for jobs using these attributes. SidesType.ONE_SIDED 853 * imposes each consecutive page upon the same side of consecutive media 854 * sheets. This imposition is sometimes called <i>simplex</i>. 855 * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages 856 * upon front and back sides of consecutive media sheets, such that the 857 * orientation of each pair of pages on the medium would be correct for 858 * the reader as if for binding on the long edge. This imposition is 859 * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes 860 * each consecutive pair of pages upon front and back sides of consecutive 861 * media sheets, such that the orientation of each pair of pages on the 862 * medium would be correct for the reader as if for binding on the short 863 * edge. This imposition is sometimes called <i>tumble</i>. Not specifying 864 * this attribute is equivalent to specifying SidesType.ONE_SIDED. 865 * 866 * @param sides SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or 867 * SidesType.TWO_SIDED_SHORT_EDGE. 868 * @throws IllegalArgumentException if sides is null. 869 */ 870 public void setSides(SidesType sides) { 871 if (sides == null) { 872 throw new IllegalArgumentException("Invalid value for attribute "+ 873 "sides"); 874 } 875 this.sides = sides; 876 } 877 878 /** 879 * Sets how consecutive pages should be imposed upon the sides of the 880 * print medium for jobs using these attributes to the default. The 881 * default imposition is SidesType.ONE_SIDED. 882 */ 883 public void setSidesToDefault() { 884 setSides(SidesType.ONE_SIDED); 885 } 886 887 /** 888 * Returns, for jobs using these attributes, the last page (inclusive) 889 * to be printed, if a range of pages is to be printed. This attribute is 890 * updated to the value chosen by the user. An application should ignore 891 * this attribute on output, unless the return value of the <code> 892 * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An 893 * application should honor the return value of <code>getPageRanges</code> 894 * over the return value of this method, if possible. 895 * 896 * @return an integer greater than zero and greater than or equal 897 * to <i>toPage</i> and greater than or equal to <i>minPage</i> 898 * and less than or equal to <i>maxPage</i>. 899 */ 900 public int getToPage() { 901 if (toPage != 0) { 902 return toPage; 903 } else if (fromPage != 0) { 904 return fromPage; 905 } else if (pageRanges != null) { 906 return prLast; 907 } else { 908 return getMinPage(); 909 } 910 } 911 912 /** 913 * Specifies, for jobs using these attributes, the last page (inclusive) 914 * to be printed, if a range of pages is to be printed. 915 * If this attribute is not specified, then the values from the pageRanges 916 * attribute are used. If pageRanges and either or both of fromPage and 917 * toPage are specified, pageRanges takes precedence. Specifying none of 918 * pageRanges, fromPage, or toPage is equivalent to calling 919 * setPageRanges(new int[][] { new int[] { <i>minPage</i> } }); 920 * 921 * @param toPage an integer greater than zero and greater than or equal 922 * to <i>fromPage</i> and greater than or equal to <i>minPage</i> 923 * and less than or equal to <i>maxPage</i>. 924 * @throws IllegalArgumentException if one or more of the above 925 * conditions is violated. 926 */ 927 public void setToPage(int toPage) { 928 if (toPage <= 0 || 929 (fromPage != 0 && toPage < fromPage) || 930 toPage < minPage || 931 toPage > maxPage) { 932 throw new IllegalArgumentException("Invalid value for attribute "+ 933 "toPage"); 934 } 935 this.toPage = toPage; 936 } 937 938 /** 939 * Determines whether two JobAttributes are equal to each other. 940 * <p> 941 * Two JobAttributes are equal if and only if each of their attributes are 942 * equal. Attributes of enumeration type are equal if and only if the 943 * fields refer to the same unique enumeration object. A set of page 944 * ranges is equal if and only if the sets are of equal length, each range 945 * enumerates the same pages, and the ranges are in the same order. 946 * 947 * @param obj the object whose equality will be checked. 948 * @return whether obj is equal to this JobAttribute according to the 949 * above criteria. 950 */ 951 public boolean equals(Object obj) { 952 if (!(obj instanceof JobAttributes)) { 953 return false; 954 } 955 JobAttributes rhs = (JobAttributes)obj; 956 957 if (fileName == null) { 958 if (rhs.fileName != null) { 959 return false; 960 } 961 } else { 962 if (!fileName.equals(rhs.fileName)) { 963 return false; 964 } 965 } 966 967 if (pageRanges == null) { 968 if (rhs.pageRanges != null) { 969 return false; 970 } 971 } else { 972 if (rhs.pageRanges == null || 973 pageRanges.length != rhs.pageRanges.length) { 974 return false; 975 } 976 for (int i = 0; i < pageRanges.length; i++) { 977 if (pageRanges[i][0] != rhs.pageRanges[i][0] || 978 pageRanges[i][1] != rhs.pageRanges[i][1]) { 979 return false; 980 } 981 } 982 } 983 984 if (printer == null) { 985 if (rhs.printer != null) { 986 return false; 987 } 988 } else { 989 if (!printer.equals(rhs.printer)) { 990 return false; 991 } 992 } 993 994 return (copies == rhs.copies && 995 defaultSelection == rhs.defaultSelection && 996 destination == rhs.destination && 997 dialog == rhs.dialog && 998 fromPage == rhs.fromPage && 999 maxPage == rhs.maxPage && 1000 minPage == rhs.minPage && 1001 multipleDocumentHandling == rhs.multipleDocumentHandling && 1002 prFirst == rhs.prFirst && 1003 prLast == rhs.prLast && 1004 sides == rhs.sides && 1005 toPage == rhs.toPage); 1006 } 1007 1008 /** 1009 * Returns a hash code value for this JobAttributes. 1010 * 1011 * @return the hash code. 1012 */ 1013 public int hashCode() { 1014 int rest = ((copies + fromPage + maxPage + minPage + prFirst + prLast + 1015 toPage) * 31) << 21; 1016 if (pageRanges != null) { 1017 int sum = 0; 1018 for (int i = 0; i < pageRanges.length; i++) { 1019 sum += pageRanges[i][0] + pageRanges[i][1]; 1020 } 1021 rest ^= (sum * 31) << 11; 1022 } 1023 if (fileName != null) { 1024 rest ^= fileName.hashCode(); 1025 } 1026 if (printer != null) { 1027 rest ^= printer.hashCode(); 1028 } 1029 return (defaultSelection.hashCode() << 6 ^ 1030 destination.hashCode() << 5 ^ 1031 dialog.hashCode() << 3 ^ 1032 multipleDocumentHandling.hashCode() << 2 ^ 1033 sides.hashCode() ^ 1034 rest); 1035 } 1036 1037 /** 1038 * Returns a string representation of this JobAttributes. 1039 * 1040 * @return the string representation. 1041 */ 1042 public String toString() { 1043 int[][] pageRanges = getPageRanges(); 1044 String prStr = "["; 1045 boolean first = true; 1046 for (int i = 0; i < pageRanges.length; i++) { 1047 if (first) { 1048 first = false; 1049 } else { 1050 prStr += ","; 1051 } 1052 prStr += pageRanges[i][0] + ":" + pageRanges[i][1]; 1053 } 1054 prStr += "]"; 1055 1056 return "copies=" + getCopies() + ",defaultSelection=" + 1057 getDefaultSelection() + ",destination=" + getDestination() + 1058 ",dialog=" + getDialog() + ",fileName=" + getFileName() + 1059 ",fromPage=" + getFromPage() + ",maxPage=" + getMaxPage() + 1060 ",minPage=" + getMinPage() + ",multiple-document-handling=" + 1061 getMultipleDocumentHandling() + ",page-ranges=" + prStr + 1062 ",printer=" + getPrinter() + ",sides=" + getSides() + ",toPage=" + 1063 getToPage(); 1064 } 1065 }